package myJs.user

import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import myJs.myPkg.jquery._
import org.scalajs.dom
import org.scalajs.dom.{Event, URL, document}
import org.scalajs.dom.html.Canvas

import scala.scalajs.js
import myJs.Implicits._
import myJs.tool.Tool
import org.scalajs.dom.ext.Ajax

import scala.scalajs.js.Dynamic.{global => g}
import scala.concurrent.ExecutionContext.Implicits.global

/**
 * Created by yz on 16/9/2021
 */
@JSExportTopLevel("Register")
object Register {

  var code: String = ""
  var canvas: Canvas = _
  var gVerify: GVerify = _

  type Ctx2D =
    dom.CanvasRenderingContext2D

  @JSExport("init")
  def init = {
    captchaInit("v_container")
    bootStrapValidator
  }

  case class GVerify(kind: String, height: Double, width: Double)

  def captchaInit(divId: String) = {
    val conJq = $(s"#${divId}")
    val width = if (conJq.innerWidth() > 0) conJq.innerWidth() else 100
    val height = if (conJq.innerHeight() > 0) conJq.innerHeight() else 30
    canvas = document.createElement("canvas").asInstanceOf[Canvas]
    canvas.width = width.toInt
    canvas.height = height.toInt
    val canvasJq = $(canvas)
    val canvasId = "verifyCanvas"
    conJq.append(canvas)
    canvasJq.attr("id", canvasId)
    canvasJq.css("cursor", "pointer").html("您的浏览器版本不支持canvas")
    gVerify = GVerify(kind = "blend", height = height, width = width)
    refresh
    canvasJq.on("click", () => {
      refresh
    })
  }

  def getAllLetter = {
    val letterStr = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"
    letterStr.split(",")
  }

  def randomNum(min: Double, max: Double) = {
    (math.random() * (max - min) + min).toInt
  }

  def randomColor(min: Int, max: Int) = {
    val r = randomNum(min, max)
    val g = randomNum(min, max)
    val b = randomNum(min, max)
    s"rgb($r,$g,$b)"
  }

  def refresh = {
    val numArr = "0,1,2,3,4,5,6,7,8,9".split(",")
    val letterArr = getAllLetter
    val ctx = canvas.getContext("2d")
      .asInstanceOf[Ctx2D]
    ctx.textBaseline = "middle"
    ctx.fillStyle = randomColor(180, 240)
    ctx.fillRect(0, 0, gVerify.width, gVerify.height)
    val txtArr = gVerify.kind match {
      case "blend" => numArr ++ letterArr
      case "number" => numArr
      case _ => letterArr
    }
    code = (1 to 4).map { i =>
      val txt = txtArr(randomNum(0, txtArr.length))
      ctx.font = randomNum(gVerify.height / 2, gVerify.height) + "px SimHei"
      ctx.fillStyle = randomColor(50, 160)
      ctx.shadowOffsetX = randomNum(-3, 3)
      ctx.shadowOffsetY = randomNum(-3, 3)
      ctx.shadowBlur = randomNum(-3, 3)
      ctx.shadowColor = "rgba(0, 0, 0, 0.3)"
      val x = gVerify.width / 5 * i
      val y = gVerify.height / 2
      val deg = randomNum(-30, 30)
      ctx.translate(x, y)
      ctx.rotate(deg * Math.PI / 180)
      ctx.fillText(txt, 0, 0)
      ctx.rotate(-deg * Math.PI / 180)
      ctx.translate(-x, -y)
      txt
    }.mkString
    (1 to 4).foreach { i =>
      ctx.strokeStyle = randomColor(40, 180)
      ctx.beginPath()
      ctx.moveTo(randomNum(0, gVerify.width), randomNum(0, gVerify.height))
      ctx.lineTo(randomNum(0, gVerify.width), randomNum(0, gVerify.height))
      ctx.stroke()
    }
    (0 to gVerify.width.toInt / 4).foreach { i =>
      ctx.fillStyle = randomColor(0, 255)
      ctx.beginPath()
      ctx.arc(randomNum(0, gVerify.width), randomNum(0, gVerify.height), 1, 0, 2 * Math.PI)
      ctx.fill()
    }
  }

  def validate(curCode: String) = {
    val codeLower = curCode.toLowerCase
    val dbCode = code.toLowerCase()
    if (codeLower == dbCode) {
      true
    } else {
      refresh
      false
    }
  }

  def bootStrapValidator = {
    val url = g.jsRoutes.controllers.UserController.accountCheck().url.toString
    val maxNumber = Double.MaxValue
    val dict: js.Dictionary[js.Any] = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "account" -> {
          val info = "账号"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "notEmpty" -> js.Dictionary(
                "message" -> s"${info}不能为空！"
              ),
              "remote" -> js.Dictionary(
                "message" -> s"${info}已存在！",
                "url" -> url,
                "delay" -> 1000,
                "type" -> "POST",
              ),
            )
          )
        },
        "password" -> {
          val info = "密码"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "notEmpty" -> js.Dictionary(
                "message" -> s"${info}不能为空！"
              ),
            )
          )
        },
        "confirmPassword" -> {
          val info = "确认密码"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "notEmpty" -> js.Dictionary(
                "message" -> s"${info}不能为空！"
              ),
              "identical" -> js.Dictionary(
                "field" -> "password",
                "message" -> "两次密码不一样!"
              ),
            )
          )
        },
        "captcha" -> {
          val info = "验证码"
          js.Dictionary(
            "validators" -> js.Dictionary(
              "notEmpty" -> js.Dictionary(
                "message" -> s"${info}不能为空！"
              ),
              "blank" -> js.Dictionary(
              )
            )
          )
        },
      )
    )
    $(s"#form").bootstrapValidator(dict).on("success.form.bv", (e: Event) => {
      e.preventDefault()
      val bv = $(s"#form").bv
      val b = validate(Tool.getInputByName("captcha").myVal)
      if (b) {
        bv.defaultSubmit()
      } else {
        bv.updateMessage("captcha", "blank", "验证码错误！")
        bv.updateStatus("captcha", "INVALID", "blank")
      }
    })
  }


}
